package mdb

import (
	"github.com/pkg/errors"
	"gopkg.in/mgo.v2"
)

//GetOne Get 查询单条数据
func GetOne(session *mgo.Session, query QueryOption, out any) (bool, error) {
	defer session.Close()
	err := session.DB(query.db).C(query.collection).Find(query.selector).One(out)
	if err != nil {
		return false, err
	} else {
		return true, nil
	}
}

// Exist 检查数据是否存在
func Exist(session *mgo.Session, query QueryOption) (bool, error) {
	defer session.Close()
	num, err := session.DB(query.db).C(query.collection).Find(query.selector).Count()
	if err != nil {
		return false, errors.Wrap(err, "check count")
	} else {
		return num > 0, nil
	}
}

// FindCount 查询总数并返回 total [D]
func FindCount(session *mgo.Session, query QueryOption) (int, error) {
	defer session.Close()
	num, err := session.DB(query.db).C(query.collection).Find(query.selector).Count()
	if err != nil {
		return 0, errors.Wrap(err, "check count")
	} else {
		return num, nil
	}
}

// FindPage 查询分页数据并返回 total [D]
func FindPage(session *mgo.Session, query QueryOption, out any) (int, error) {
	defer session.Close()
	count, err := session.DB(query.db).C(query.collection).Find(query.selector).Count()
	if err != nil {
		return 0, errors.Wrap(err, "find count")
	} else if count == 0 {
		return 0, nil
	}
	if query.skip < 0 || query.limit < 0 {
		return count, nil
	}
	iter := session.DB(query.db).C(query.collection).Find(query.selector).Sort(query.sort...).Skip(query.skip).Limit(query.limit).Iter()
	_ = iter.All(out)
	return count, nil
}

// FindPageNoTotal 查询分页数据
func FindPageNoTotal(session *mgo.Session, query QueryOption, out any) error {
	defer session.Close()
	if query.skip < 0 || query.limit < 0 {
		return nil
	}
	iter := session.DB(query.db).C(query.collection).Find(query.selector).Sort(query.sort...).Skip(query.skip).Limit(query.limit).Iter()
	_ = iter.All(out)
	return nil
}

// Insert 插入数据
func Insert(session *mgo.Session, query QueryOption, in any) error {
	defer session.Close()
	return session.DB(query.db).C(query.collection).Insert(in)
}

// Update 更新数据
func Update(session *mgo.Session, query QueryOption) error {
	defer session.Close()
	return session.DB(query.db).C(query.collection).Update(query.selector, query.updateM)
}

// UpdateAll 更新所有数据
func UpdateAll(session *mgo.Session, query QueryOption) error {
	defer session.Close()
	_, err := session.DB(query.db).C(query.collection).UpdateAll(query.selector, query.updateM)
	return err
}
